package org.example.autofilearchiver.tool.PDF;
import org.apache.pdfbox.multipdf.PDFMergerUtility;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.encryption.InvalidPasswordException;
import org.apache.pdfbox.text.PDFTextStripper;
import com.itextpdf.text.Document;
import com.itextpdf.text.pdf.PdfCopy;
import com.itextpdf.text.pdf.PdfImportedPage;
import com.itextpdf.text.pdf.PdfReader;
import lombok.AllArgsConstructor;
import lombok.Data;
import org.example.autofilearchiver.tool.fileTool.FileUtils;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
import java.util.List;

/**
 * 处理pdf文件的工具类
 */
@Data
@AllArgsConstructor

public class PDFTool {
    /**
     * 实现pdf文件的每页拆分
     * @param filePath 输入的pdf文件路径
     * @param newFile 生成的pdf文件夹路径
     * @param from 起始拆分页数
     * @param end 结束拆分页数
     * @throws IOException 抛异常
     */
    public static void pdftoone(String filePath, String newFile, int from, int end) throws IOException {
        //  判断路径存在性
        FileUtils.createDirectoriesIfNotExists(newFile);
        Document document = null;
        PdfCopy copy = null;
        try {
            PdfReader reader = new PdfReader(filePath);
            //总页数
            int n = reader.getNumberOfPages();
            if (end == 0) {
                end = n;
            }
            document = new Document(reader.getPageSize(1));
            copy = new PdfCopy(document, new FileOutputStream(newFile));
            document.open();
            for (int j = from; j <= end; j++) {
                document.newPage();
                PdfImportedPage page = copy.getImportedPage(reader, j);
                copy.addPage(page);
            }
            document.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 直接拆分pdf的每一页生成新文件存到对应文件夹里去
     * @param inPath 输入的pdf文件路径
     * @param outPath 生成的pdf文件夹路径
     * @throws IOException 抛异常
     */
    public static void splitPdf(String inPath, String outPath) throws IOException {

        PdfReader reader = new PdfReader(inPath);
        //总页数
        int n = reader.getNumberOfPages();
        reader.close();
        for (int i = 1; i <= n; i++) {
            pdftoone(inPath, outPath + i + ".pdf", i, i);
        }

    }
    /**
     * 通过标识数据重命名pdf文件，放到指定文件夹
     * @param pdfPath 原始放pdf的文件夹
     * @param tags 标识数据
     * @param pdfPath2 指定文件夹
     */
    public static void pdfFilesRenameWithTags(String pdfPath, List<String> tags, String pdfPath2) {
        List<String> allFilePaths = FileUtils.getAllFilePaths(pdfPath);
        for (int i = 0; i < allFilePaths.size(); i++) {
            String filePath = allFilePaths.get(i);
            copyAndRenameFileWithPdfSuffix(tags.get(i), filePath, pdfPath2);
        }
    }
    /**
     * 传入pdf文件，改名并复制到指定路径
     *
     * @param name                  要改的名字
     * @param sourceFilePath        源文件路径
     * @param destinationFolderPath 指定的新路径(文件夹)
     */
    public static void copyAndRenameFileWithPdfSuffix(String name, String sourceFilePath, String destinationFolderPath) {
        // 创建Path对象
        Path sourceFile = Paths.get(sourceFilePath);
        Path destinationFolder = Paths.get(destinationFolderPath);
        Path destinationFile = destinationFolder.resolve(name + ".pdf");

        try {
            // 确保目标文件夹存在
            if (!Files.exists(destinationFolder)) {
                Files.createDirectories(destinationFolder);
            }

            // 复制文件并覆盖（如果已存在）
            Files.copy(sourceFile, destinationFile, StandardCopyOption.REPLACE_EXISTING);

            System.out.println("文件已成功复制到 " + destinationFile.toString());
        } catch (IOException e) {
            System.err.println("复制文件时出错: " + e.getMessage());
        }
    }
    /**
     * 读取 PDF 文件中的文字
     * @param filePath PDF 文件的绝对路径
     * @return 包含所有文字的列表
     */
    public static List<String> getPdfText(String filePath) {
        List<String> textList = new ArrayList<>();
        try (PDDocument document = PDDocument.load(new File(filePath))) {
            // 创建 PDFTextStripper 对象
            PDFTextStripper stripper = new PDFTextStripper();
            // 逐行读取 PDF 文本
            String[] lines = stripper.getText(document).split("\\r?\\n");
            for (String line : lines) {
                textList.add(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return textList;
    }

    /**
     * 合并PDF文件，并将被合并的文件删除（保留第一个文件）
     *
     * @param filePaths 包含PDF文件绝对路径的列表
     */
    public static void mergePDFs(List<String> filePaths) {
        // 检查文件路径列表是否为空或为null
        if (filePaths == null || filePaths.isEmpty()) {
            System.out.println("文件路径列表为空或为null");
            return;
        }

        // 获取第一个文件的路径，作为合并后的文件路径
        String firstFilePath = filePaths.get(0);
        File firstFile = new File(firstFilePath);

        // 创建PDFMergerUtility实例，用于合并PDF文件
        PDFMergerUtility merger = new PDFMergerUtility();

        try {
            // 遍历文件路径列表，将每个PDF文件添加到合并工具中
            for (String filePath : filePaths) {
                File file = new File(filePath);
                if (file.exists()) {
                    merger.addSource(file); // 添加文件到合并工具
                } else {
                    System.out.println("文件不存在: " + filePath); // 如果文件不存在，输出提示信息
                }
            }

            // 设置合并后的文件路径（与第一个文件路径相同）
            merger.setDestinationFileName(firstFilePath);

            // 执行合并操作
            merger.mergeDocuments(null);

            // 输出合并成功的提示信息
            System.out.println("PDF文件已成功合并到: " + firstFilePath);

            // 合并完成后，删除被合并的文件（从第二个文件开始）
            for (int i = 1; i < filePaths.size(); i++) {
                File fileToDelete = new File(filePaths.get(i)); // 获取要删除的文件
                if (fileToDelete.delete()) { // 尝试删除文件
                    System.out.println("已删除文件: " + filePaths.get(i)); // 删除成功，输出提示信息
                } else {
                    System.out.println("无法删除文件: " + filePaths.get(i)); // 删除失败，输出提示信息
                }
            }

        } catch (IOException e) {
            // 捕获并处理合并过程中可能发生的异常
            e.printStackTrace();
            System.out.println("合并PDF文件时发生错误: " + e.getMessage());
        }
    }

}
